package com.bskj.kuaifu.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSONObject;
import com.bskj.common.constants.CommonConstatns;
import com.bskj.common.utils.EncryptUtil;
import com.bskj.common.utils.Global;
import com.bskj.common.utils.LogUtils;
import com.bskj.common.utils.StringUtils;
import com.bskj.kuaifu.common.RequestLoggerUtils;

/**
 * 参数解密过滤器
 *
 * @author lishi
 * @date 2017-12-18 下午5:09:55
 */
public class ParamDecryptFilter implements MyFilter {
	private MyFilter next;

	private Set<String> prefixIignores = new HashSet<String>();

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;

		RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(httpServletRequest);

		String host = httpServletRequest.getHeader("host");
		String uri = httpServletRequest.getRequestURI();
		String queryStr = httpServletRequest.getQueryString();
		String allUrl = Global.getConfig("HTTP_PREFIX") + "://" + host + uri;
		if (!StringUtils.isBank(queryStr)) {
			allUrl += "?" + queryStr;
		}
		LogUtils.debug("url:" + allUrl);

		requestParameterWrapper.addParameter("url", allUrl);

		if (canIgnore(httpServletRequest)) {
			if (next != null) {
				next.doFilter(requestParameterWrapper, response, chain);
			} else {
				chain.doFilter(requestParameterWrapper, response);
			}
			return;
		}

		String params = request.getParameter("params");
		LogUtils.debug("params:" + params);
		if (StringUtils.isBank(params)) {
			//TODO 参数错误
			return;
		} else {
			try {
				Map<String, Object> extraParams = new HashMap<String, Object>();
				String paramJsonStr = EncryptUtil.decrypt(params, CommonConstatns.AES_KEY);
				String requestStr = String.format(
						"request URL : %s |  before decrypt params ： 【%s】  | after decrypt params : 【%s】", allUrl,
						params, paramJsonStr);
				RequestLoggerUtils.debug(requestStr);
				JSONObject paramJSON = JSONObject.parseObject(paramJsonStr);
				extraParams.putAll(paramJSON);
				requestParameterWrapper.addParameters(extraParams);
				requestParameterWrapper.removeAttribute("params");
				if (next != null) {
					next.doFilter(requestParameterWrapper, response, chain);
				} else {
					chain.doFilter(requestParameterWrapper, response);
				}
				return;
			} catch (Exception e) {
				e.printStackTrace();
				LogUtils.error("Exception:" + e);
				return;
			}
		}
	}

	private boolean canIgnore(HttpServletRequest request) {
		String url = request.getRequestURI();
		String contextPath = request.getContextPath();
		for (String ignore : prefixIignores) {
			if (url.startsWith(contextPath + ignore)) {
				return true;
			}
		}
		return false;
	}

	public Set<String> getPrefixIignores() {
		return prefixIignores;
	}

	public void setPrefixIignores(Set<String> prefixIignores) {
		this.prefixIignores = prefixIignores;
	}

	public MyFilter next() {
		return next;
	}

	public void setNext(MyFilter myFitler) {
		this.next = myFitler;
	}

	public static String getIpAddr(HttpServletRequest request) {

		String ip = request.getHeader("X-Real-IP");

		if (!StringUtils.isBank(ip) && !"unknown".equalsIgnoreCase(ip)) {
			return ip;
		}

		ip = request.getHeader("X-Forwarded-For");

		if (!StringUtils.isBank(ip) && !"unknown".equalsIgnoreCase(ip)) {
			// 多次反向代理后会有多个IP值，第一个为真实IP。
			int index = ip.indexOf(',');
			if (index != -1) {
				return ip.substring(0, index);
			} else {

				return ip;
			}

		} else {
			return request.getRemoteAddr();
		}
	}
}
